module libeventd.http.Intelnal;

import
	libeventd.Types;

enum{
	HTTP_CONNECT_TIMEOUT	= 45,
	HTTP_WRITE_TIMEOUT	= 50,
	HTTP_READ_TIMEOUT	= 50,
	HTTP_DEFAULTPORT	= 80,
}

const HTTP_PREFIX	= "http://";

enum message_read_status {
	ALL_DATA_READ = 1,
	MORE_DATA_EXPECTED = 0,
	DATA_CORRUPTED = -1,
	REQUEST_CANCELED = -2,
	DATA_TOO_LONG = -3
}

enum evhttp_connection_error {
	EVCON_HTTP_TIMEOUT,
	EVCON_HTTP_EOF,
	EVCON_HTTP_INVALID_HEADER,
	EVCON_HTTP_BUFFER_ERROR,
	EVCON_HTTP_REQUEST_CANCEL
}
enum evhttp_connection_state {
	EVCON_DISCONNECTED,	/**< not currently connected not trying either*/
	EVCON_CONNECTING,	/**< tries to currently connect */
	EVCON_IDLE,		/**< connection is established */
	EVCON_READING_FIRSTLINE,/**< reading Request-Line (incoming conn) or
				 **< Status-Line (outgoing conn) */
	EVCON_READING_HEADERS,	/**< reading request/response headers */
	EVCON_READING_BODY,	/**< reading request/response body */
	EVCON_READING_TRAILER,	/**< reading request/response chunked trailer */
	EVCON_WRITING		/**< writing request/response headers/body */
}

enum{
	EVHTTP_CON_INCOMING	= 0x0001,
	EVHTTP_CON_OUTGOING	= 0x0002,
	EVHTTP_CON_CLOSEDETECT  = 0x0004,
}


extern(C):


struct evhttp_connection {
	TAILQ_ENTRY!(evhttp_connection)		next;

	evutil_socket_t	fd;
	bufferevent*	bufev;

	event		retry_ev;		/* for retrying connects */

	char*		bind_address;	/* address to use for binding the src */
	ev_ushort		bind_port;		/* local port for binding the src */

	char*		address;		/* address to connect to */
	ev_ushort		port;

	size_t		max_headers_size;
	ev_uint64_t 	max_body_size;

	ev_int		flags;
	ev_int		timeout;		/* timeout in seconds for events */
	ev_int		retry_cnt;		/* retry count */
	ev_int		retry_max;		/* maximum number of retries */

	evhttp_connection_state
				state;
	evhttp*		http_server;
	evcon_requestq	requests;

	void function(evhttp_connection*, void*)
				cb;
	void*		cb_arg;

	void function(evhttp_connection*,void*)
				closecb;
	void*		closecb_arg;

	deferred_cb read_more_deferred_cb;

	event_base*	base;
	evdns_base*	dns_base;
}

struct evhttp_cb {
	TAILQ_ENTRY!(evhttp_cb) next;
	char *what;
	void function(evhttp_request*, void*) cb;
	void *cbarg;
}

struct evcon_requestq{
	mixin TAILQ_HEAD!(evhttp_request);
}

struct evconq{
	mixin TAILQ_HEAD!(evhttp_connection);
}

struct httpcbq{
	mixin TAILQ_HEAD!(evhttp_cb);
}


struct vhostsq{
	mixin TAILQ_HEAD!(evhttp);
}

struct evhttp_bound_socket {
	TAILQ_ENTRY!(evhttp_bound_socket)	next;
	evconnlistener*	listener;
}

struct boundq{
	mixin TAILQ_HEAD!(evhttp_bound_socket);
}

struct evhttp_server_alias {
	TAILQ_ENTRY!(evhttp_server_alias) next;
	char* _alias;
}

struct aliasq{
	mixin TAILQ_HEAD!(evhttp_server_alias);
}

struct evhttp {
	TAILQ_ENTRY!(evhttp)	next_vhost;
	boundq		sockets;
	httpcbq		callbacks;
	evconq		connections;
	vhostsq		virtualhosts;
	aliasq		aliases;
	char*		vhost_pattern;
	ev_int		timeout;
	size_t		default_max_headers_size;
	ev_uint64_t	default_max_body_size;
	ev_uint16_t allowed_methods;
	void function(evhttp_request*,void*)	gencb;
	void*		gencbarg;
	event_base*	base;
}